/*
 * CS_WORLD_BOSS_PARTY_INVITE_RES.cpp
 *
 *  Created on: 2014. 1. 13.
 *      Author: jjaehuny
 */


#include "../../Command.h"

#include "../../User.h"
#include "../../NLogic/Space.h"
#include "../../NLogic/Static.h"
#include "../../NLogic/Stamina.h"

#include "Common.h"

namespace ProjectZ { namespace NCommand {

static void SendAck_CS_WORLD_BOSS_PARTY_INVITE_RES(User * pUser, int16_t ack)
{
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	* pAck << static_cast<int16_t>(ack);
	pAck->MakePacket(CMD_SC_WORLD_BOSS_PARTY_INVITE_RES);
	pUser->Send(pAck);
}

void Command::CS_WORLD_BOSS_PARTY_INVITE_RES(User * pUser, ::Network::Packet * pPacket)
{
	/*
	CS_WORLD_BOSS_PARTY_INVITE_RES		0x401A
	{
		u32	party_seq;
		u8	answer;			// 0:no, 1:yes
	}
	*/

	NLogic::Space * pWorld = pUser->GetSpace();
	if (NULL == pWorld)
	{
		DEBUGLOG("%s NULL == pWorld", __FUNCTION__);
		SendAck_CS_WORLD_BOSS_PARTY_INVITE_RES(pUser, ACK_NO_SPACE);
		return;
	}

	if (pWorld->GetData()._spaceType != NLogic::Space::SpaceType::WORLD)
	{
		DEBUGLOG("%s pWorld->GetData()._spaceType != NLogic::Space::SpaceType::WORLD", __FUNCTION__);
		SendAck_CS_WORLD_BOSS_PARTY_INVITE_RES(pUser, ACK_NO_SPACE);
		return;
	}

	if (pUser->GetEnumState() != User::EnumState::INVITE)
	{
		DEBUGLOG("%s pUser->GetEnumState() != User::EnumState::INVITE", __FUNCTION__);
		SendAck_CS_WORLD_BOSS_PARTY_INVITE_RES(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	NLogic::Battle * pBattle = pUser->GetBattle();
	if (NULL == pBattle)
	{
		DEBUGLOG("%s NULL == pBattle", __FUNCTION__);
		SendAck_CS_WORLD_BOSS_PARTY_INVITE_RES(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	PREPARE_PACKET;

	uint32_t party_seq = 0;
	uint8_t answer = 0;
	* pPacket >> party_seq >> answer;

	NLogic::Static::WORLDBOSSROOMTREE & worldBossRoomTree = NLogic::Static::Instance().GETWORLDBOSSROOMTREE_FRIEND();
	auto itr = worldBossRoomTree.find(party_seq);
	if (itr == worldBossRoomTree.end())
	{
		SendAck_CS_WORLD_BOSS_PARTY_INVITE_RES(pUser, ACK_NOT_PARTY);
		return;
	}

	NLogic::Space * pWorldBossSpace = itr->second;

	NLogic::Party * pParty = pWorldBossSpace->GetParty();
	if (NULL == pParty)
	{
		SendAck_CS_WORLD_BOSS_PARTY_INVITE_RES(pUser, ACK_NOT_PARTY);
		return;
	}

	if (NLogic::Party::State::WORLD_BOSS_WAIT_FRIEND != pParty->GetState())
	{
		SendAck_CS_WORLD_BOSS_PARTY_INVITE_RES(pUser, ACK_START_BATTLE);
		return;
	}

	if (static_cast<int>(pParty->GetAllUserTree().size()) > pWorldBossSpace->GetData()._maxUser + 1)
	{
		SendAck_CS_WORLD_BOSS_PARTY_INVITE_RES(pUser, ACK_START_BATTLE);
		return;
	}

	auto finditr = pParty->GetInviteUserTree().find(pUser->GetUserSeq());
	if (finditr == pParty->GetInviteUserTree().end())
	{
		SendAck_CS_WORLD_BOSS_PARTY_INVITE_RES(pUser, ACK_NOT_PARTY);
		return;
	}

	if (0 == answer)
	{
		pUser->SetEnumState(User::EnumState::__NONE__);

		pParty->LeaveUser(pUser);
		pParty->AddRefuseCount();

		return;
	}

	NLogic::Stamina * pStamina = pUser->GetStamina();
	if (NULL == pStamina)
	{
		DEBUGLOG("%s NULL == pStamina", __FUNCTION__);
		SendAck_CS_WORLD_BOSS_PARTY_INVITE_RES(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	if (true == pStamina->IsKeyLack(1))
	{
		DEBUGLOG("%s staminaGap < 0", __FUNCTION__);
		SendAck_CS_WORLD_BOSS_PARTY_INVITE_RES(pUser, ACK_NOT_ENOUGHT_STAMINA);

		pUser->SetEnumState(User::EnumState::__NONE__);

		pParty->LeaveUser(pUser);
		pParty->AddRefuseCount();

		return;
	}

/*	time_t currentSec;
	time(&currentSec);

	// 현재 스태미너가 최대라면 남은 회복 시간을 현재시간으로 설정
	if (pUser->GetCharacterInfo().event_stamina == STAMINA_MAX)
		pUser->GetCharacterInfo().recover_stamina_sec = currentSec;

	int staminaGap = pUser->GetCharacterInfo().event_stamina - 1;

	// 보유 스태미너가 부족한 경우
	if (staminaGap < 0)
	{
		DEBUGLOG("%s staminaGap < 0", __FUNCTION__);
		SendAck_CS_WORLD_BOSS_PARTY_INVITE_RES(pUser, ACK_NOT_ENOUGHT_STAMINA);

		pUser->SetEnumState(User::EnumState::__NONE__);

		pParty->LeaveUser(pUser);
		pParty->AddRefuseCount();

		return;
	}*/

	User * pMaster = pParty->GetMaster();
	if (NULL == pMaster)
	{
		SendAck_CS_WORLD_BOSS_PARTY_INVITE_RES(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	pWorld->LeaveUser(pUser);
	pUser->SetEnumState(User::EnumState::ACCEPT_WAIT);
	pParty->AddInviteUserTree(pUser);

	pBattle->GetData().bReadyFight = false;

	pWorldBossSpace->EnterUser(pUser);

	SendWorldBossDetailInfo(pUser);

//	{	// send sn party join
//		::Network::Packet * pNoti = ::Network::GETPACKETPOOL()->SEND_NEW();
//		* pNoti << pUser->GetUserSeq();
//		pNoti->MakePacket(CMD_SN_REQ_WORLD_BOSS_PARTY_JOIN);
//		pWorldBossSpace->SendAllExceptMe(pNoti, pUser);
//	}

	::Network::Packet * pNoti = ::Network::GETPACKETPOOL()->SEND_NEW();
	* pNoti << pUser->GetUserSeq();
	pNoti->MakePacket(CMD_SN_REQ_WORLD_BOSS_PARTY_JOIN);

	auto partyAllUserTree = pParty->GetAllUserTree();
	std::for_each(partyAllUserTree.begin(), partyAllUserTree.end(), [&](NLogic::Party::USERTREE::value_type & pair) {
		User * pLocal = pair.second;

		if (pUser != pLocal)
		{
			pLocal->SendOneshotEncrypt(pNoti);
		}
	} );

	::Network::GETPACKETPOOL()->SEND_DEL(pNoti);

//	if (pParty->GetInviteUserTree().size() == 0 || pParty->GetAcceptUserTree().size() >= MAX_PARTY_DUNGEON_INVITE + 1)
//	{
//		auto partyAllUserTree = pParty->GetAllUserTree();
//
//		::Network::Packet * pNoti = ::Network::GETPACKETPOOL()->SEND_NEW();
//		* pNoti << static_cast<int16_t>(ACK_OK);
//		* pNoti << static_cast<uint8_t>(partyAllUserTree.size());
//
//		std::for_each(partyAllUserTree.begin(), partyAllUserTree.end(), [&](NLogic::Party::USERTREE::value_type & pair) {
//			User * pUser = pair.second;
//			uint32_t u32gid = static_cast<uint32_t>(pUser->GetUserSeq());
//			* pNoti << u32gid;
//			pUser->SetEnumState(User::EnumState::READY_WAIT);
//		} );
//
//		pNoti->MakePacket(CMD_SN_PARTY_CREATE_DONE);
//		pWorldBossSpace->SendAll(pNoti);
//
//		pParty->SetState(NLogic::Party::State::READY_WAIT);
//		pParty->GetMaster()->SetEnumState(User::EnumState::READY_WAIT);
//
//		return;
//	}
}

} /*NCommand*/ } /*ProjectZ*/



